package org.acghub.mtdb.common;


import org.acghub.mtdb.common.type.TypeDateTime;

import java.time.LocalDateTime;
import java.util.*;


/**
 * @author zhouhe
 */
public final class ObjectUtil {

    public static final String HASHCODE = ObjectUtil.class.getName() + ".hashCode";
    public static final String EQUALS = ObjectUtil.class.getName() + ".equals";
    public static final String NOT_EQUALS = "!" + EQUALS;
    public static final String CONVERT = ObjectUtil.class.getName() + ".convert";
    public static final String NON_NULL = ObjectUtil.class.getName() + ".nonNull";

    public static boolean isNull(Object obj) {
        return cn.hutool.core.util.ObjectUtil.isEmpty(obj);
    }

    public static boolean nonNull(Object obj) {
        return cn.hutool.core.util.ObjectUtil.isNotEmpty(obj);
    }

    public static <T> T convert(String value, Class<T> clazz) {
        if (clazz.equals(LocalDateTime.class) || clazz.equals(TypeDateTime.class)) {
            return (T) TypeDateTime.parse(value);
        }
        return cn.hutool.core.convert.Convert.convert(clazz, value);
    }

    public static int hashCode(Object o) {
        if (o == null) {
            return 0;
        }
        if (o instanceof Collection<?> && !((Collection<?>) o).isEmpty()) {
            int hash = 0;
            for (Object e : ((Collection<?>) o)) {
                hash ^= e.hashCode();
            }
            return hash;
        } else if (o instanceof Map<?, ?> && !((Map<?, ?>) o).isEmpty()) {
            int hash = 0;
            for (Map.Entry<?, ?> entry : ((Map<?, ?>) o).entrySet()) {
                hash ^= entry.getKey().hashCode();
                hash ^= entry.getValue().hashCode();
            }
            return hash;
        } else if (o instanceof CharSequence && !((CharSequence) o).isEmpty()) {
            return o.hashCode();
        }
        return o.hashCode();
    }

    public static <T> boolean equals(T o1, T o2) {
        return Objects.equals(o1, o2);
    }

    public static <E> boolean equals(Collection<E> e1, Collection<E> e2) {
        if (e1 == e2) {
            return true;
        }
        if (e1 == null || e2 == null || e1.size() != e2.size()) {
            return false;
        }
        if (e1.isEmpty()) {
            return true;
        }
        for (Iterator<E> ite1 = e1.iterator(), ite2 = e2.iterator(); ite1.hasNext() && ite2.hasNext(); ) {
            if (!equals(ite1.next(), ite2.next())) {
                return false;
            }
        }
        return true;
    }

    public static <K, V> boolean equals(Map<K, V> m1, Map<K, V> m2) {
        if (m1 == m2) {
            return true;
        }
        if (m1 == null || m2 == null || m1.size() != m2.size()) {
            return false;
        }
        if (m1.isEmpty()) {
            return true;
        }
        Set<K> ks1 = m1.keySet(), ks2 = m2.keySet();
        if (!ks1.containsAll(ks2)) {
            return false;
        }
        for (K k : ks1) {
            if (!equals(m1.get(k), m2.get(k))) {
                return false;
            }
        }
        return true;
    }

}
